/*
 * Copyright (c) 2010 - 2011, Brookhaven National Laboratory
 * All rights reserved.
 * The software in this package is published under the terms
 * of the BSD license a copy of which has been included with
 * this distribution in the license.txt file.
 */

package org.oxtypes.impl.modifiable;

import java.util.List;
import java.util.ArrayList;

import org.omg.dds.type.TypeKind;
import org.omg.dds.type.dynamic.DynamicType;
import org.omg.dds.type.dynamic.TypeDescriptor;
import org.omg.dds.type.dynamic.modifiable.ModifiableTypeDescriptor;

import org.oxtypes.impl.DDSObjectImpl;

public class ModifiableTypeDescriptorImpl extends DDSObjectImpl
        implements ModifiableTypeDescriptor {

    public ModifiableTypeDescriptorImpl(){
        body = new TypeDescriptorImpl();
    }
    
    // --- From Value: ---------------------------------------------------

    public ModifiableTypeDescriptor modify(){
        modifiable = true;
        return this;
    }

    // --- From ModifiableValue: ------------------------------------

    public ModifiableTypeDescriptor copyFrom(TypeDescriptor other){

        body.typeKind = other.getKind();
        body.name     = other.getName();

        body.baseType = other.getBaseType();
        body.discType = other.getDiscriminatorType();
        body.elemType = other.getElementType();
        body.keyType  = other.getKeyElementType();

        body.bound    = other.getBound();

        return this;
    }

    public TypeDescriptor finishModification(){
        modifiable = false;
        return body.clone();
    }

    public ModifiableTypeDescriptor clone(){
        throw new java.lang.UnsupportedOperationException();
    }
    
    // --- From TypeDescriptor -------------------------------------------

    public boolean isConsistent(){
        throw new java.lang.UnsupportedOperationException();
    }

    public TypeKind getKind(){
        return body.getKind();
    }

    public String getName(){
        return body.getName();
    }

    public DynamicType getBaseType(){
        return body.getBaseType();
    }

    public DynamicType getDiscriminatorType(){
        return body.getDiscriminatorType();
    }

    public List<Integer> getBound(){
        return body.getBound();
    }

    public DynamicType getElementType(){
        return body.getElementType();
    }

    public DynamicType getKeyElementType(){
        return body.getKeyElementType();
    }

    // --- From ModifiableTypeDescriptor -----------------------------------

    public ModifiableTypeDescriptor setKind(TypeKind kind){
        if(modifiable) body.typeKind = kind;
        return this;
    }

    public ModifiableTypeDescriptor setName(String name){
        if(modifiable) body.name = name;
        return this;
    }

    public ModifiableTypeDescriptor setBaseType(DynamicType baseType){
        if(modifiable) body.baseType = baseType;
        return this;
    }

    public ModifiableTypeDescriptor setDiscriminatorType(DynamicType discriminatorType){
        if(modifiable) body.discType = discriminatorType;
        return this;
    }

    public ModifiableTypeDescriptor setBound(int... bounds){
        if(modifiable == false) return this;
        body.bound = new ArrayList<Integer>(bounds.length);
        for(int bound: bounds){
            body.bound.add(bound);
        }
        return this;
    }

    public ModifiableTypeDescriptor setElementType(DynamicType elementType){
        if(modifiable) body.elemType = elementType;
        return this;
    }

    public ModifiableTypeDescriptor setKeyElementType(DynamicType keyElementType){
        if(modifiable) body.keyType = keyElementType;
        return this;
    }
    
    private TypeDescriptorImpl body;
    private boolean modifiable = true;

    private class TypeDescriptorImpl extends DDSObjectImpl
            implements TypeDescriptor {

        private TypeDescriptorImpl(){
        }

        // --- From Value: ---------------------------------------------------

        @Override
        public TypeDescriptor clone(){

            TypeDescriptorImpl result = new TypeDescriptorImpl();

            result.typeKind = typeKind;
            result.name     = name;

            result.baseType = baseType;
            result.discType = discType;
            result.elemType = elemType;
            result.keyType  = keyType;

            if(bound != null) {
                result.bound = new ArrayList<Integer>(bound.size());
                java.util.Collections.copy(result.bound, bound);
            }

            return result;
        }

        public ModifiableTypeDescriptor modify(){
            return null;
        }

        // --- From TypeDescriptor: -----------------------------------------

        public boolean isConsistent(){
            return true;
        }

        public TypeKind getKind(){
            return typeKind;
        }

        public String getName(){
            return name;
        }

        public DynamicType getBaseType(){
            return baseType;
        }

        public DynamicType getDiscriminatorType(){
            return discType;
        }

        public List<Integer> getBound(){
            if(bound == null) return null;
            return java.util.Collections.unmodifiableList(bound);
        }

        public DynamicType getElementType(){
            return elemType;
        }

        public DynamicType getKeyElementType(){
            return keyType;
        }

        private TypeKind typeKind;
        private String name;

        private DynamicType baseType;
        private DynamicType discType;
        private DynamicType elemType;
        private DynamicType keyType;

        private List<Integer> bound;

    }


}
